#ifdef MTC7000_TOUCH_SCREEN_SUPPORT
#include <types.h>
#include <gapi.h>
#include <event.h>
#include <drivers/input/input.h>
#include <drivers/input/touchscr.h>
#include "io.h"
#include "system.h"
#include "sys/alt_irq.h"
#include "altera_avalon_timer_regs.h"
//ap include
//#include <ioboard.h>

struct touch_operations mtc7000_ops = {
    .open = mtc7000_open,
    .close = mtc7000_close,
    .rectify = mtc7000_rectify,
    .polling = mtc7000_polling,
};

struct input_device mtc7000_dev = {-1, &mtc7000_ops, 0 };
extern struct input_device *inp_dev;
extern int xres, yres;

/*
volatile int xm = 1;
volatile int xd = 1;
volatile int xcdot = 0;
volatile int xcpos = 0;
volatile int ym = 1;
volatile int yd = 1;
volatile int ycdot = 0;
volatile int ycpos = 0;
*/
volatile int xm = -700;
volatile int xd = -2844;
volatile int xcdot = 50;
volatile int xcpos = 589;
volatile int ym = -150;
volatile int yd = 778;
volatile int ycdot = 400;
volatile int ycpos = 1405;
volatile int cnt = 0;
volatile int touch_flag = FLAG_NONE;
volatile int touch_flag_save = FLAG_NONE;
volatile COORD raw = {0, 0};
volatile COORD xy;

//0.05s
#define timer_start() \
        IOWR(TIMER_BASE, ALTERA_AVALON_TIMER_PERIODL_REG, 0x4b3f); \
        IOWR(TIMER_BASE, ALTERA_AVALON_TIMER_PERIODH_REG, 0x4c); \
        IOWR(TIMER_BASE, ALTERA_AVALON_TIMER_CONTROL_REG, 0x05)

#define timer_stop() \
        IOWR(TIMER_BASE, ALTERA_AVALON_TIMER_PERIODL_REG, 0x4b3f); \
        IOWR(TIMER_BASE, ALTERA_AVALON_TIMER_PERIODH_REG, 0x4c); \
        IOWR(TIMER_BASE, ALTERA_AVALON_TIMER_CONTROL_REG, 0x09)
        
void timer_isr()
{
    touch_flag = FLAG_RELEASE;
    //printf(".");
    IOWR(TIMER_BASE, ALTERA_AVALON_TIMER_STATUS_REG, 0x0);
}

int mtc7000_open(void)
{
    mtc7000_dev.dev_id = 0x7000;
    mtc7000_draw_rectifier();
    return 0;
}

void mtc7000_close(void)
{
    mtc7000_dev.dev_id = -1;
}

void mtc7000_rectify(COORD dot1, COORD dot2, COORD pos1, COORD pos2)
{
    xm = dot1.x - dot2.x;
    xd = pos1.x - pos2.x;
    if(dot1.x > dot2.x) {
      xcdot = dot2.x;
      xcpos = pos2.x;
    }
    else {
      xcdot = dot1.x;
      xcpos = pos1.x;
    }
    ym = dot1.y - dot2.y;
    yd = pos1.y - pos2.y;
    if(dot1.y > dot2.y) {
      ycdot = dot2.y;
      ycpos = pos2.y;
    }
    else {
      ycdot = dot1.y;
      ycpos = pos1.y;
    }
    printf("xm, xd, xcdot, xcpos, ym, yd, ycdot, ycpos=%d,%d,%d,%d,%d,%d,%d,%d\n",xm, xd, xcdot, xcpos, ym, yd, ycdot, ycpos);
}

#ifdef NON_OS
void mtc7000_isr()
{
    volatile u32 data;
    data = IORD(UART_0_BASE, 0);
    switch(cnt)
    {
        case 0:
            if(data & 0x80) {
                touch_flag_save = FLAG_PRESS;
                timer_start();
                cnt++;
            }
            else {
                touch_flag = FLAG_NONE;
                touch_flag_save = FLAG_NONE;
                cnt = 0;
            }
            break;
        case 1:
            if(data & 0x80) {
                touch_flag = FLAG_NONE;
                touch_flag_save = FLAG_NONE;
                cnt = 0;
            }
            else {
                xy.x = data & 0x7f;
                timer_start();
                cnt++;
            }
            break;
        case 2:
            if(data & 0x80) {
                touch_flag = FLAG_NONE;
                touch_flag_save = FLAG_NONE;
                cnt = 0;
            }
            else {
                xy.x = (data << 7) | xy.x;
                timer_start();
                cnt++;
            }
            break;
        case 3:
            if(data & 0x80) {
                touch_flag = FLAG_NONE;
                touch_flag_save = FLAG_NONE;
                cnt = 0;
            }
            else {
                xy.y = data & 0x7f;
                timer_start();
                cnt++;
            }
            break;
        case 4:
            if(data & 0x80) {
                touch_flag = FLAG_NONE;
                touch_flag_save = FLAG_NONE;
                cnt = 0;
            }
            else {
                xy.y = (data << 7) | xy.y;
                cnt = 0;
                raw = xy;
                touch_flag = touch_flag_save;
                //printf("x: %d, y: %d, flag: %d\n", xy.x, xy.y, touch_flag);
            }
            break;
    }
}
#endif

int mtc7000_init(void)
{
    int ret = 0;
    inp_dev = &mtc7000_dev;

    /* Enable interrupts */
    //uart
    IOWR(UART_0_BASE, 0x03, 0x0180);
    alt_irq_register(UART_0_IRQ , NULL, mtc7000_isr);
    //timer
    IOWR(TIMER_BASE, ALTERA_AVALON_TIMER_CONTROL_REG, 0x09);
    IOWR(TIMER_BASE, ALTERA_AVALON_TIMER_STATUS_REG, 0x0);
    alt_irq_register(TIMER_IRQ , NULL, timer_isr);
    //holdboard timer
    //init_timer_holdboard();
    if(inp_dev->touch_ops->open)
        ret = inp_dev->touch_ops->open();
    return ret;
}

void mtc7000_polling(EVENT *e)
{
    //while(touch_flag == FLAG_NONE);
    e->flag = touch_flag;
    //printf("FLAG: %d\n", e->flag);
    if(e->flag == FLAG_NONE)
        return;
    e->pos.x = ((raw.x - xcpos) * xm / xd) + xcdot;
    e->pos.y = ((raw.y - ycpos) * ym / yd) + ycdot;
    touch_flag = FLAG_NONE;
    //if(e->flag == FLAG_PRESS)
    //    printf("P ");
    //else if(e->flag == FLAG_RELEASE)
    //    printf("R\n");
}

void mtc7000_draw_rectifier(void)
{
    RECT rect;
    DOT dot;
    EVENT event;
    COORD vis_lp, vis_rp, real_lp, real_rp;

    /* Initialize base coordinate for rectifying */
    vis_lp.x = 50;
    vis_lp.y = 400;
    vis_rp.x = 750;
    vis_rp.y = 550;

    /* Draw first dot at (50,50) */
    //DPRINTF("Drawing rectify background\n");
    rect.x = 0;
    rect.y = 350;
    rect.width = xres;
    rect.height = 250;
    rect.color = pCOLOR_BLACK;
    rect.filled = true;
    rect.tp = false;
    DrawRect(&rect);

    dot.size = 10;
    dot.x = vis_lp.x - dot.size/2;
    dot.y = vis_lp.y - dot.size/2;
    dot.color = pCOLOR_WHITE;
    dot.tp = false;
    DrawDot(&dot);
    
    /* Wait for first touch */
    printf("waiting for first touch\n");
    touch_flag = FLAG_NONE;
    do
    {
        mtc7000_polling(&event);
    }while(event.flag != FLAG_RELEASE);
    
    real_lp.x = raw.x;//event.pos.x;
    real_lp.y = raw.y;//event.pos.y;
    printf("Point1 x: %d, y: %d\n", real_lp.x, real_lp.y);
    
    DrawRect(&rect);
    //DPRINTF("Drawing rectify dot 2\n");
    dot.size = 10;
    dot.x = vis_rp.x - dot.size/2;
    dot.y = vis_rp.y - dot.size/2;
    dot.color = pCOLOR_WHITE;
    dot.tp = false;
    DrawDot(&dot);

    /* Wait for second touch */
    printf("waiting for second touch\n");
    touch_flag = FLAG_NONE;
    do
    {
        mtc7000_polling(&event);
    }while(event.flag != FLAG_RELEASE);
    real_rp.x = raw.x;
    real_rp.y = raw.y;
    printf("Point2 x: %d, y: %d\n", real_rp.x, real_rp.y);
    
    mtc7000_rectify(vis_lp, vis_rp, real_lp, real_rp);
}

void mtc7000_exit(void)
{
    if(inp_dev->touch_ops->close)
        inp_dev->touch_ops->close();
    inp_dev = NULL;
}
#endif
